home *** CD-ROM | disk | FTP | other *** search
/ Black Crawling Systems Archive Release 1.0 / Black Crawling Systems Archive Release 1.0 (L0pht Heavy Industries, Inc.)(1997).ISO / advisories / LC15SRC.ZIP / util.c < prev    next >
C/C++ Source or Header  |  1997-07-11  |  8KB  |  243 lines

  1. #include "includes.h"
  2.  
  3. void str_to_key(unsigned char *str,unsigned char *key);
  4. void usage(char *progname);
  5. void fill_user_struct(int, char *dastring, struct user_struct *da_struct);
  6. void LMword(char *passwd, char *word);
  7. char *atob(char *hexstring,int size);
  8. int htoi(char c);
  9. int PutUniCode(char *dst,char *src);
  10. int isvalid_userline(int, char *str);
  11.  
  12. /*
  13.  * Convert a 7 byte array into an 8 byte des key with odd parity.
  14.  */
  15.  
  16. void str_to_key(unsigned char *str,unsigned char *key)
  17. {
  18.     void des_set_odd_parity(des_cblock *);
  19.     int i;
  20.  
  21.     key[0] = str[0]>>1;
  22.     key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
  23.     key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
  24.     key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
  25.     key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
  26.     key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
  27.     key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
  28.     key[7] = str[6]&0x7F;
  29.     for (i=0;i<8;i++) {
  30.         key[i] = (key[i]<<1);
  31.     }
  32.     des_set_odd_parity((des_cblock *)key);
  33. }
  34.  
  35.  
  36. void usage(char *progname){
  37.    char *p;
  38.  
  39.    p = strrchr(progname, '\\');
  40.    if (p == NULL)
  41.     p = progname;
  42.    else
  43.     p++;
  44.  
  45.    fprintf(stderr, "Usage: %s -p <pwfile> -w <wordlist> -o <ofile> -b"
  46.         " [-l || n]\n", p);
  47.    fprintf(stderr, "     -p <pwfile> The password file to read from in pwdump format\n");
  48.    fprintf(stderr, "     -P <pwfile> The password file to read from in sniffer format\n");
  49.    fprintf(stderr, "     -w <wordlist> The dictionary of words to try\n");
  50.    fprintf(stderr, "     -o <ofile> File to write results to - if not\n");
  51.    fprintf(stderr, "                specified defaults to stdout\n");
  52.    fprintf(stderr, "     -b Brute force through the entire keyspace\n");
  53.    fprintf(stderr, "          <A-Z takes 26 hours on PPRO 200>\n");
  54.    fprintf(stderr, "     -l Only go after the LANMAN password\n");
  55.    fprintf(stderr, "     -n Only go after the NT Dialect password [dumb!]\n");
  56.    fprintf(stderr, "          without the -l or -n it goes after both\n");
  57.    fprintf(stderr, "          which is still much faster than going after\n");
  58.    fprintf(stderr, "          the NT Dialect password only!\n");
  59.    fprintf(stderr, "\n");
  60.    fprintf(stderr, "  Note: Both -p and -w are required, unless -b is"
  61.         " specified\n");
  62.    fprintf(stderr, "        in which case -w must be ommited\n");
  63.    fprintf(stderr, "             mudge@l0pht.com\n");
  64.    exit(1);
  65. }
  66.  
  67. void fill_user_struct(int pwdump, char *dastring, struct user_struct *da_struct){
  68.     char *tmp, *atobstr;
  69.  
  70.         /* clear out the sucker */
  71.     memset(da_struct, '\0', sizeof(struct user_struct)); 
  72.  
  73.     da_struct->pwdumpval = pwdump;
  74.  
  75.   if (pwdump){
  76.     strncpy(da_struct->username, strtok(dastring, ":"), 128);
  77.     strtok(NULL, ":"); /* skip over UID */
  78.     tmp = strtok(NULL, ":");
  79.     if (strncmp(tmp, "NO PASSWORD", 11) == 0){
  80.       strcpy(da_struct->lmhash, "DISABLED?");
  81.       strcpy(da_struct->nthash, "DISABLED?");
  82.     } else if (strncmp(tmp, "********", 8) == 0){
  83.         strcpy(da_struct->lmhash, "NULL PASSWD?");
  84.         strcpy(da_struct->nthash, "NULL PASSWD?");
  85.     } else {
  86.         strncpy(da_struct->lmhash, tmp, 32);
  87.         strncpy(da_struct->nthash, strtok(NULL, ":"), 32);
  88.     }
  89.  
  90.     if ((strncmp(da_struct->lmhash, "DISABLED?", 9) != 0) \
  91.            && (strncmp(da_struct->lmhash, "NULL PASSWD?", 12) != 0 )){
  92.       atobstr = atob(da_struct->lmhash, 32);
  93.       memcpy(da_struct->lmhashb, atobstr, 16);
  94.       free(atobstr);
  95.  
  96.       atobstr = atob(da_struct->nthash, 32);
  97.       memcpy(da_struct->nthashb, atobstr, 16);
  98.       free(atobstr);
  99.     }
  100.  
  101.     /* if the second part of the lanman key is 0xAAD3B435B51404EE then 
  102.            the password is 7 chars or less and we don't need to spin the 
  103.            extra CPU cycles */
  104.     if (memcmp(&(da_struct->lmhash[16]), "AAD3B435B51404EE", 16) == 0)
  105.       da_struct->under7 = 1;
  106.     else
  107.       da_struct->under7 = 0;
  108.   } else { /* we are reading from a sniffer file */
  109.     strncpy(da_struct->username, strtok(dastring, ":"), 128);
  110.     tmp = strtok(NULL, ":"); /* get the password length */
  111.     if (atoi(tmp) >= 7)
  112.       da_struct->under7 = 0;
  113.     else
  114.       da_struct->under7 = 1;
  115.  
  116.     tmp = strtok(NULL, ":"); /* get the 8byte challenge - note that we
  117.                                 have it stored in ascii so it is 16 bytes
  118.                                 to begin with */
  119.     atobstr = atob(tmp, 16);
  120.     memcpy(da_struct->server_chall, atobstr, 8);
  121.     free(atobstr);
  122.  
  123.     tmp = strtok(NULL, ":");
  124.     atobstr = atob(tmp, 48);
  125.     memcpy(da_struct->lmresp_b, atobstr, 24);
  126.     free(atobstr);
  127.  
  128.     tmp = strtok(NULL, ":");
  129.     atobstr = atob(tmp, 48);
  130.     memcpy(da_struct->ntresp_b, atobstr, 24);
  131.     free(atobstr);
  132.   }
  133.  
  134.   da_struct->lmdone = 0;
  135.   da_struct->ntdone = 0;
  136.   da_struct->already_printed = 0;
  137.  
  138.   da_struct->next = NULL;
  139.   da_struct->previous = NULL;
  140.  
  141. }
  142.  
  143. void LMword(char *passwd, char *word){
  144.     size_t i;
  145.     int word_len;
  146.  
  147.     word_len = strlen(word);
  148.  
  149.     for (i=0; i < word_len; i++)
  150.         word[i] = toupper(word[i]);
  151.  
  152.     if (word_len < 14){
  153.         memcpy(passwd, word, strlen(word));
  154.         for (i=0; i<= (strlen(passwd)); i++){
  155.           if ((passwd[i] == '\r') || (passwd[i] == '\n'))
  156.             passwd[i] = '\0';
  157.         }
  158.     }
  159.     else
  160.         memcpy(passwd, word, 14);
  161. }
  162.  
  163. /* the routines atob() and htoi() were lifted from code by
  164.    Josh Daymont - with only minor modifications */
  165. char *atob(char *hexstring,int size) {
  166.     int i, value;
  167.     unsigned char c;
  168.     char *str1, *str2;
  169.  
  170.     value = (size/2)+1;
  171.     str1 = (char *)(malloc((unsigned)value));
  172.     str2 = str1; /* save pointer to beginning */
  173.     for (i=0; i<size-1; i+=2){
  174.       if((value = htoi(*hexstring++)) == -1)
  175.          return(0); 
  176.       c = value << 4;
  177.       if((value = htoi(*hexstring++)) == -1)
  178.         return(0);
  179.       c |= value;
  180.       *str1++ = (char)c;
  181.     }
  182.     return(str2);
  183. }
  184.  
  185. int htoi(char c)
  186. {
  187.         if (c == 32) return(0);
  188.         if('0' <= c && c <= '9')
  189.                 return c - '0';
  190.         if('a' <= c && c <= 'f')
  191.                 return 10 + c - 'a';
  192.         if('A' <= c && c <= 'F')
  193.                 return 10 + c - 'A';
  194.         return -1;
  195. }
  196.  
  197. /*******************************************************************
  198. write a string in unicoode format
  199. ********************************************************************/
  200. int PutUniCode(char *dst,char *src)
  201. {
  202.   int ret = 0;
  203.   while (*src) {
  204.     dst[ret++] = src[0];
  205.     dst[ret++] = 0;    
  206.     src++;
  207.   }
  208.   dst[ret++]=0;
  209.   dst[ret++]=0;
  210.   return(ret-2); /* the way they do the md4 hash they don't represent 
  211.             the last null. ie 'A' becomes just 0x41 0x00 - not 
  212.             0x41 0x00 0x00 0x00 */
  213. }
  214.  
  215. /* quick scan of line read from password file and a return of 1 if it's 
  216.    superficially valid, 0 otherwise - This should really be flushed out 
  217.    and made more intelligent */
  218. int isvalid_userline(int pwdump, char *str){
  219.     unsigned int i, counter;
  220.     
  221.     counter = 0;
  222.  
  223.         for (i=0; i < strlen(str); i++){
  224.       if (str[i] == ':')
  225.         counter++;
  226.       }
  227.  
  228. #ifdef _DEBUG
  229.   if (pwdump)
  230.     fprintf(stderr, "file is a pwdump file and line has %d delimiters\n", \
  231.                                                                       counter);
  232.   else
  233.     fprintf(stderr, "file is a sniffer file and line has %d delimiters\n", \
  234.                                                                      counter); 
  235. #endif
  236.  
  237.     if ((pwdump && (counter == 6)) || (!(pwdump) && (counter == 4)))
  238.         return(1);
  239.     else
  240.         return(0);
  241. }
  242.  
  243.